#include <my_header.h>


typedef struct train_s {
    int length;
    
    char data[1000];
} train_t;//客户端和服务端协议设计要一致

int recvn(int sockfd, void *buf, ssize_t length){
    char *p = (char *)buf;//char* 是因为偏移以1个字节为单位
    ssize_t cursize = 0;
    while(cursize < length){
        ssize_t sret = recv(sockfd,p+cursize,length-cursize,0);
        cursize += sret;
    }
    return 0;
}

//下载
int putsfile(int sockfd, char *filename) {
    train_t train;
    
    // 1. 接收文件总大小
    recvn(sockfd, &train.length, sizeof(train.length));
    recvn(sockfd, train.data, train.length);
    off_t filesize;
    memcpy(&filesize, train.data, train.length);
    printf("filesize = %ld\n", filesize);
    
    // 检查本地文件是否存在及已下载大小
    off_t local_size = 0;
    struct stat statbuf;
    if (stat(filename, &statbuf) == 0) {
        local_size = statbuf.st_size;
        printf("Local file exists, size = %ld\n", local_size);
    }
    
    // 2. 发送已接收的大小给服务端
    train.length = sizeof(local_size);
    memcpy(train.data, &local_size, train.length);
    send(sockfd, &train, sizeof(train.length) + train.length, MSG_NOSIGNAL);
    
    // 打开文件，如果是续传则追加写入
    int flags = O_WRONLY | O_CREAT;
    if (local_size > 0) {
        flags |= O_APPEND;
        printf("Resuming download from %ld\n", local_size);
    } else {
        flags |= O_TRUNC;
    }
    
    int fd = open(filename, flags, 0666);
    ERROR_CHECK(fd, -1, "open putsfile");
    
    off_t cursize = local_size;
    off_t lastsize = local_size;
    off_t slice = filesize / 10000;
    
    while (1) {
        bzero(train.data, sizeof(train.data));
        recvn(sockfd, &train.length, sizeof(train.length));
        
        if (train.length == 0) {
            break;
        }
        
        recvn(sockfd, train.data, train.length);
        write(fd, train.data, train.length);
        
        cursize += train.length;
        if (cursize - lastsize > slice) {
            printf("%5.2lf%%\r", 100.0 * cursize / filesize);
            fflush(stdout);
            lastsize = cursize;
        }
    }
    
    printf("100.00%%\n");
    close(fd);
    return 0;
}

